import { reactive } from 'vue'

// 简易可复用表单校验钩子
// 使用：
// const { errors, validate } = useFormValidator(form, {
//   field: [required('提示'), minLength(6, '至少6位')]
// })

export function useFormValidator(form, rules) {
  const errors = reactive({})

  const clear = () => {
    Object.keys(rules || {}).forEach(k => { errors[k] = '' })
  }

  const validate = () => {
    clear()
    let ok = true
    for (const [field, fieldRules] of Object.entries(rules || {})) {
      const value = getValue(form, field)
      for (const rule of fieldRules || []) {
        const passed = rule.test(value, form)
        if (!passed) {
          errors[field] = rule.message
          ok = false
          break
        }
      }
    }
    return ok
  }

  return { errors, validate, clear }
}

// 规则构造器
export const required = (message = '必填项') => ({
  message,
  test: (v) => {
    if (typeof v === 'boolean') return v === true
    return v !== undefined && v !== null && String(v).trim() !== ''
  }
})

export const minLength = (min, message) => ({
  message: message || `至少${min}位`,
  test: (v) => (v || '').length >= min
})

export const pattern = (re, message) => ({
  message: message || '格式不正确',
  test: (v) => (v == null || String(v) === '') ? true : re.test(String(v))
})

export const email = (message = '请输入有效的邮箱地址') => pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, message)
export const phoneCN = (message = '请输入有效的手机号码') => pattern(/^1[3-9]\d{9}$/, message)

export const equalsTo = (otherField, message = '两次输入不一致') => ({
  message,
  test: (v, form) => String(v) === String(getValue(form, otherField))
})

export const custom = (fn, message) => ({
  message: message || '校验失败',
  test: (v, form) => !!fn(v, form)
})

function getValue(form, field) {
  // 支持ref/reactive对象
  const obj = form && (form.value ?? form)
  return obj ? obj[field] : undefined
}